;------------------------------------------------------ ; ; Monitor multi-firmware per start-up ; computer Z80 Nuova Elettronica ; ; Copyright Roberto Bazzano 2006 - 2024 ; ;------------------------------------------------------ ; ; BANCHI 2 e 3 - Allocati da F800h a FFFFh ; ; NOTA: durante tutto il codice il registro B' contiene 00h se c'è la scheda video vecchia. Se non c'è contiene FFh ; Il registro C' contiene il numero della pagina di menù visualizzata a video ; Il registro D' se <> 00h indica che la routine "input" deve controllare anche il backspace (utilizzato dal programma di test della ram) ; NOTA: I registri alternativi non vengono utilizzati dai monitor esadecimali ; ;------------------------------------------------------ ; .org 00000h ; solo per debug con simulatore ;------------------------------------------------------ banco .equ 05fh ; porta di I/O per la selezione del banco di memoria della EPROM menu1 .equ 0f000h ; routines ed indirizzi presenti in monitor1.asm menu2 .equ 0f200h menu3 .equ 0f400h curs .equ 0f5f0h out0 .equ 0f600h out1 .equ out0+8 out2 .equ out1+8 out3 .equ out2+8 out4 .equ out3+8 out5 .equ out4+8 out6 .equ out5+8 out7 .equ out6+8 out8 .equ out7+8 out9 .equ out8+8 out10 .equ out9+8 out11 .equ out10+8 .org 0f800h ; JUMP table jp start ; F800h inizio firmware jp input ; F803h routine input da tastiere per monitor esadecimale jp video ; F806h routine output video per monitor esadecimale (visualizza su monitor vecchio, nuovo, e display tastiera esadecimale) jp lf0a5 ; F809h routine f0a5h identica a quella della eprom 2390 (inizializza i registri del SY6545 ed i PIO) jp lf060 ; F80Ch routine f060h identica a quella della eprom 2390 (carica in R14, R15, R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare) jp lf06e ; F80Fh routine f06eh identica a quella della eprom 2390 (carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare) jp checv ; F812h routine calcolo presenza scheda video vecchia jp chect ; F815h routine controllo presenza scheda video vecchia jp waitv ; F818h routine di attesa ritraccia video vecchio jp waitn ; F81Bh routine di attesa ritraccia video nuovo jp writen ; F81Eh routine di scrittura carattere sul video nuovo jp cursor ; F821h routine di accensione/spegnimento cursore sul video nuovo jp vloc ; F824h calcola la locazione del video vecchio in base alla riga/colonna nella locazione puntata da HL e HL+1 per il video vecchio jp nloc ; F827h calcola la locazione del video nuovo in base alla riga/colonna nella locazione puntata da HL e HL+1 per il video nuovo jp vloc1 ; F82Ah calcola la locazione del video vecchio in base alla riga/colonna contenute in BC jp nloc1 ; F82Dh calcola la locazione del video nuovo in base alla riga/colonna contenute in BC jp initv ; F830h pulizia video vecchio jp initn ; F833h pulizia video nuovo jp ctabdi ; F836h calcola l'indirizzo della tabella TABDIS, per la conversione dei valori da visualizzare sui display, e lo ritorna in HL jp vdisp ; F839h visualizza un messaggio puntato da HL sui display jp vdispc ; F83Ch visualizza il carattere contenuto in A sul display puntato da C, convertendolo nel formato compatibile con i caratteri dei display start: di ; disabilita gli interrupt ld hl,045edh ; inizializza il vettore per l'NMI ld (0066h),hl ; mettendo l'istruzione RETN (ED 45) xor a ; spegne il motore del floppy out (0d6h),a exx ; inizializza il registro D' in modo che l'input da tastiera NON controlli anche il backspace ld d,a exx ld a,28h ; seleziona il banco con le subroutines. IMPORTANTE: questo banco deve rimanere sempre selezionato durante l'esecuzione del monitor multifirmware out (banco),a ;------------------------------------------------------ ; Lancia test ram se al boot è stato premuto ESC (sulle tastiere alfanumeriche) o CTRL+F (sulla tastiera esadecimale) ;------------------------------------------------------ ld a,0cfh ; inizializza il PIO 1/B (tastiera) out (87h),a xor a dec a out (87h),a tram1: ; controlla se esiste la scheda video vecchia ld hl,00000h ; inizializza il contatore tram2: inc hl ; attende al massimo fino a che HL non diventa 1000h ld a,h ; infatti la ritraccia a "1" come tempo resta al massimo con HL a 0111h cp 10h ; se impiega più tempo significa che la scheda LX.388 non è presente jr z,tram3 ; ha superato il timeout, quindi la scheda video vecchia non c'è in a,(0ebh) ; controlla se c'è la ritraccia video bit 7,a jr nz,tram2 ; ritraccia non trovata, looppa ld hl,03000h ; fa un ritardo per permettere alle tastiere di assestarsi all'accensione o al reset tram2a: dec hl ld a,h or l jr nz,tram2a in a,(0eah) ; controlla se c'è un tasto premuto sulla tastiera vecchia bit 7,a jr nz,tram5 ; tasto premuto sulla tastiera vecchia tram3: in a,(085h) ; controlla se c'è un tasto premuto sulla tastiera nuova cpl bit 7,a jr nz,tram5 ; tasto premuto sulla tastiera nuova ld bc,01ffh ; controlla se c'è un tasto premuto sulla tastiera esadecimale tram4: in a,(0f0h) ; fa 255 input. Quello che è il bin 7 a 0 è il tasto premuto (a causa del contatore hardware che fa lo scan dei tasti) bit 7,a jr z,tram8 ; tasto premuto sulla tastiera esadecimale dec bc ld a,b or c jr nz,tram4 jr sp0 ; nessun tasto premuto tram5: and 7fh ; controlla se è stato premuto ESC su una tastiera alfanumerica cp 01bh jr nz,sp0 tram6: ld hl,out11 ; visualizza "test ram" sui display ld bc,08F7h tram7: ld a,(hl) out (c),a inc hl dec c dec b xor a cp b jr nz,tram7 ld a,26h ; seleziona il banco del programma per il test della ram out (banco),a jp 0f000h ; salta al programma per il test della ram tram8: cp 01fh ; controlla se è stato premuto CTRL+F sulla tastiera esadecimale jr z,tram6 ;------------------------------------------------------ sp0: ld hl,0ebffh ; cerca dove posizionare lo SP prima di EC00 sp1: ld a,(hl) cpl ld (hl),a cp (hl) jr z,sp3 sp2: dec hl jr sp1 sp3: cpl ld (hl),a cp (hl) jr nz,sp2 ld sp,hl call lf0a5 ; inizializza i registri del SY6545 ed i PIO call checv ; imposta il registro B' che indica se esiste la scheda video vecchia tast0: ld hl,out0 ; visualizza il messaggio "SELECT" sui display call msg call vmenu1 ; pulisce i video e visualizza il menù tast0a: call input ; input da tastiere push af ; salva il numero digitato cp 10h jr z,tast0c ; se è stato premuto CR salta subito al controllo del tasto cp 13h ; se è maggiore di SHIFT+2 looppa jr nc,tast0a cp 01h ; se è minore di 1 looppa jr c,tast0a ld hl,curs ; calcola la posizione sul video vecchio per visualizzare il numero digitato call vloc ; calcola in DE l'indirizzo del video in base alla riga/colonna nella locazione puntata da HL e HL+1 cp 11h ; confronta il numero digitato con 11h call convnu ; converte il numero nei caratteri che rappresentano la voce di menù (AF non viene toccato) jr nc,tast0b ; se il numero digitato è >=11h e quindi deve visualizzare due caratteri va a tast0b ld a,l ; recupera il carattere da visualizzare ld (de),a ; visualizza il carattere sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato jr tast0c tast0b: ld a,h ; recupera il primo carattere da visualizzare ld (de),a ; visualizza il primo carattere sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato inc de ; punta alla posizione del successivo carattere a video ld a,l ; recupera il secondo carattere da visualizzare ld (de),a ; visualizza il secondo carattere sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato inc de ; punta alla posizione del successivo carattere a video ld a,'<' ; visualizza il carattere "<" ld (de),a ; sul video vecchio call writen ; e sul video nuovo - Il cursore è già posizionato tast0c: pop af ; ripristina il numero digitato ld hl,tabtas ; calcola il puntatore all'indirizzo della routine presente nella tabella TABTAS e ci salta jp punt tast1: ; se 1 lancia il boot del basic da 5.5 K ld hl,out8 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,19h ; seleziona il banco del basic da 5.5 K su floppy out (banco),a jp 0f000h tast2: ; se 2 lancia il boot vecchio ld hl,out1 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,00h ; seleziona il banco della 1390 out (banco),a jp 0f000h tast3: ; se 3 lancia il boot grafic ld hl,out2 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,01h ; seleziona il banco della 2390 out (banco),a jp 0f000h tast4: ; se 4 lancia il boot del S.O.N.E. ld hl,out9 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,1Ah ; seleziona il banco del s.o.n.e. out (banco),a jp 0f000h tast5: ; se 5 lancia il basic in rom rilocato in ram ld hl,out3 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,08h ; seleziona il primo banco del basic in rom ld de,00000h tast5a: call setban ; sposta gli 8 banchi da 2K in ram inc a inc a cp 18h jr nz,tast5a jp 0000h ; salta al basic tast6: ; se 6 lancia il monitor esadecimale originale non rilocato call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,04h ; seleziona il banco del monitor esadecimale originale ld de,08000h ; seleziona il banco indicato da A e lo sposta in ram call setban jp 8000h tast7: ; se 7 lancia il monitor esadecimale non rilocato con lo SP rilocato prima di EC00 con il firmware non rilocato per il programmatore di eprom call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,20h ; seleziona il banco del monitor esadecimale con SP rilocato ld de,08000h ; seleziona il banco indicato da A e lo sposta in ram call setban jp 8000h tast8: ; se 8 lancia il monitor esadecimale rilocato con lo SP rilocato prima di EC00 per la tastiera alfanumerica con il firmware rilocato per il programmatore di eprom call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,1Ch ; seleziona il banco del monitor esadecimale rilocato per la tastiera alfanumerica out (banco),a jp 0f000h tast9: ; se 9 lancia il monitor esadecimale rilocato con lo SP rilocato prima di EC00 per la tastiera esadecimale con il firmware rilocato per il programmatore di eprom call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,1Eh ; seleziona il banco del monitor esadecimale rilocato per la tastiera esadecimale out (banco),a jp 0f000h tastA: ; se A lancia direttamente il bootstrap multiplo ld hl,out5 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,06h ; seleziona il banco della 2390 modificata per non fare il check sul disco di boot out (banco),a jp 0f17dh ; salta direttamente al BOOT tastB: ; se B lancia il loader del basic da 5.5 K call disp1 ; non visualizza alcun messaggio sui display e inizializza i video ld a,04h ; seleziona il banco del monitor esadecimale originale ld de,08000h ; seleziona il banco indicato da A e lo sposta in ram call setban ld a,18h ; seleziona il banco del loader del basic da 5.5 K su cassetta ld de,00000h ; seleziona il banco indicato da A e lo sposta in ram call setban jp 0069h ; salta al loader tastC: ; se C lancia la prova tastiera ld hl,out6 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,24h ; seleziona il banco del programma con la prova tastiera out (banco),a jp 0f000h tastD: ; se D salta a 0000h ld hl,out7 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video jp 0000h tastE: ; se E salta a 1000h ld hl,out7 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video jp 01000h tastF: ; se F sposta le routines di stampa per monitor esadecimale a 0070 ld a,07h ; seleziona il banco delle routines di stampa ld de,00070h ; seleziona il banco indicato da A e lo sposta in ram call setban ld a,28h ; seleziona il banco delle subroutines out (banco),a jp tast0 tast10: ; se RETURN cambia pagina di menù exx ; carica il numero di pagina visualizzata in A ld a,c exx inc a ; punta alla pagina successiva cp 04h ; se è minore di 4 va bene jr c,tast1a ld a,01h ; altrimenti carica la prima pagina tast1a: ld hl,tabmen ; calcola il puntatore all'indirizzo della routine presente nella tabella TABMEN e ci salta call punt ; effettua una CALL anziché un JP perché le routines vmenu1-2-3 escono con un RET jp tast0a ; ritorna all'input da tastiera tast11: ; se SHIFT+1 lancia il programma per la conversione dei datamark dei floppy ld hl,out10 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,22h ; seleziona il banco del monitor esadecimale rilocato per la tastiera alfanumerica out (banco),a jp 0f000h tast12: ; se SHIFT+2 lancia il programma per il test della ram ld hl,out11 ; messaggio da visualizzare sul display call disp ; visualizza il messaggio sui display e inizializza i video ld a,26h ; seleziona il banco del programma per il test della ram out (banco),a jp 0f000h ;------------------------------------------------------ ; converte il numero nella voce di menù ; ritorna HL contentente i due caratteri da visualizzare che sono blank+numero, oppure S+numero convnu: ld h,020h ; 020h=blank push af ; visualizza il numero digitato cp 010h ; se A < 010h jr c,convn1 ld h,053h ; 053h="S" - converte in "S"+numero sub 010h convn1: cp 0Ah jr c,convn2 ; se A < 0ah addiziona 30h, altrimenti addiziona 07h quindi addiziona 30h add a,07h ; il risultato è che se A >= 0ah addiziona 037h, altrimenti 030h convn2: add a,030h ld l,a pop af ret ;------------------------------------------------------ ; calcola il puntatore ad una tabella di jump presente in HL e salta punt: push af push bc dec a ; decrementa A, lo moltiplica per 2 e lo addiziona ad HL sla a ld c,a xor a ld b,a add hl,bc ; HL ora punta all'indirizzo da richiamare che è presente nella tabella ld c,(hl) ; carica il contenuto dell'indirizzo puntato da HL in BC inc hl ld b,(hl) push bc ; sposta BC su HL pop hl pop bc pop af jp (hl) ; salta alla routine calcolata ;------------------------------------------------------ ; visualizza il messaggio sui display, spegne il cursore sul video nuovo e inizializza i video ; Se HL=0 non visualizza il messaggio sui display ; Sporca AF disp: call msg ; Visualizza il messaggio indicato da HL sui display disp1: ld a,20h ; Spegne il cursore sul video nuovo call cursor call initv ; Inizializza il video vecchio call initn ; Inizializza il video nuovo ret ;------------------------------------------------------ ; Seleziona il banco indicato da A e lo sposta all'indirizzo indicato da DE ; Sporca tutti i registri setban: out (banco),a ; seleziona il banco ld hl,0f000h ; sposta il banco in ram ld bc,0800h ldir ret ;------------------------------------------------------ ; controlla se la scheda video vecchia è presente. Per farlo verifica il cambiamento della ritraccia video ; se la scheda video vecchia esiste ritorna 00h in B' ; se la scheda video vecchia non esiste ritorna FFh in B' checv: push af push hl exx ; mette 00h in B' ld b,00h exx ld hl,00000h ; inizializza il contatore checv1: inc hl ; attende al massimo fino a che HL non diventa 1000h ld a,h ; Infatti la ritraccia a "1" come tempo resta al massimo con HL a 0111h cp 10h ; Se impiega più tempo significa che la scheda LX.388 non è presente jr nz,checv2 exx ; se la LX.388 non è presente carica FF in B' ed esce ld b,0ffh exx jr checv3 checv2: in a,(0ebh) ; controlla se c'è la ritraccia video bit 7,a jr nz,checv1 ; ritraccia non trovata, looppa checv3: pop hl pop af ret ;------------------------------------------------------ ; controlla se è stata rilevata la scheda video vecchia ; ritorna Z a 0 se non c'è, Z a 1 se c'è ; Sporca F chect: push bc ; salva il valore di A nel registro B ld b,a exx ; recupera il valore dal registro B' ld a,b exx or a ; imposta il flag Z ld a,b ; recupera il valore di A dal registro B pop bc ret ;------------------------------------------------------ ; pulizia del video vecchio initv: push hl push de push bc ld hl,0ec00h ld de,0ec01h ld (hl),20h ld bc,01ffh call waitv ; attende la ritraccia ldir pop bc pop de pop hl ret ;------------------------------------------------------ ; attende la ritraccia del video vecchio waitv: push af call chect ; esce se non esiste la scheda video vecchia jr nz,waitv2 waitv1: in a,(0ebh) ; attende la ritraccia video bit 7,a jr nz,waitv1 waitv2: pop af ret ;------------------------------------------------------ ; pulizia del video nuovo initn: push af push hl ld hl,0h initn1: call lf06e ; carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare ld a,20h ; imposta il carattere a "blank" call writen ; scrive il carattere inc hl ld a,l cp 81h jr nz,initn1 ld a,h cp 07h jr nz,initn1 pop hl pop af ret ;------------------------------------------------------ ; accende o spegne il cursore sul video nuovo ; A=00h accende, A=20h spegne cursor: push af ld a,0ah ; seleziona il registro R10 out (8ch),a pop af ; scrive il valore out (8dh),a ret ;------------------------------------------------------ ; Subroutine per la visualizzazione del menù sui video ; vmenu1: ld hl,menu1 ; visualizza la 1° pagina del menu exx ; carica in C' il numero della pagina visualizzata ld c,01h exx jr vis vmenu2: ld hl,menu2 ; visualizza la 2° pagina del menu exx ; carica in C' il numero della pagina visualizzata ld c,02h exx jr vis vmenu3: ld hl,menu3 ; visualizza la 3° pagina del menu exx ; carica in C' il numero della pagina visualizzata ld c,03h exx vis: call disp1 ; pulisce i video push af vis1: push hl call nloc ; calcola in DE l'indirizzo del video nuovo in base alla riga/colonna nella locazione puntata da HL e HL+1 push de pop hl call lf06e ; carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare pop hl call vloc ; calcola in DE l'indirizzo del video vecchio in base alla riga/colonna nella locazione puntata da HL e HL+1 vis2: ld a,(hl) ; recupera il carattere da scrivere call waitv ; attende la ritraccia del video vecchio ld (de),a ; visualizza il carattere sul video vecchio inc de call writen ; attende la ritraccia e visualizza il carattere sul video nuovo inc hl xor a ; controlla se il prossimo carattere è 00h cp (hl) jr nz,vis2 inc hl cpl ; controlla se il prossimo carattere è 0ffh cp (hl) ; se no, ricarica la successiva prima posizione e looppa jr nz,vis1 ld hl,curs ; calcola in DE l'indirizzo del cursore in base alla riga/colonna nella locazione puntata da HL e HL+1 call nloc push de pop hl call lf060 ; carica in R14, R15, R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare xor a ; accende il cursore sul video nuovo call cursor pop af ret ;------------------------------------------------------ ; scrive il carattere presente in A sul video nuovo writen: call waitn ; attende la ritraccia out (80h),a ; scrive il carattere push af ld a,1fh ; imposta gli attributi del carattere out (8eh),a ld a,31 ; update out (8ch),a xor a out (8dh),a pop af ret ;------------------------------------------------------ ; attende la ritraccia del video nuovo waitn: push af waitn1: in a,(8ch) bit 7,a jr z,waitn1 pop af ret ;------------------------------------------------------ ; Calcola la locazione del video in base alla riga/colonna nella locazione puntata da HL e HL+1 ; Chiamare "vloc" per il video vecchio, "nloc" per il video nuovo ; Ritorna DE. HL punterà al primo carattere da visualizzare ; Sporca DE e HL ; Con l'entry-point vloc1 il registro BC deve contenere il valore della riga/colonna vloc: push bc ld b,(hl) ; numero riga inc hl ld c,(hl) ; numero colonna jr vloc1a vloc1: push bc vloc1a: push af push hl ld hl,0ec00h ; prima locazione del video vecchio ld de,00020h ; numero di caratteri che compongono una riga sul video vecchio jr loc1 nloc: push bc ld b,(hl) ; numero riga inc hl ld c,(hl) ; numero colonna jr nloc1a nloc1: push bc nloc1a: push af push hl ld hl,00158h ; indirizzo del primo carattere più offset (0158h) per centrare la videata sul video nuovo ld de,00050h ; numero di caratteri che compongono una riga sul video nuovo loc1: ld a,b ; aggiunge il numero di caratteri che compongono una riga per tutte le righe richieste or a ; cp 00h jr z,loc2 add hl,de ; somma il numero di caratteri dec b jr loc1 loc2: ld b,00h ; aggiunge il numero di caratteri relativi alla colonna richiesta add hl,bc ex de,hl ; mette il risultato in DE pop hl pop af pop bc inc hl ; punta al primo carattere del messaggio ret ;------------------------------------------------------ ; Visualizza il messaggio puntato da HL sui display della tastiera esadecimale msg: push af push bc ld bc,08F7h msg1: ld a,(hl) out (c),a inc hl dec c dec b xor a cp b jr nz,msg1 pop bc pop af ret ;------------------------------------------------------ ; ; Nuova routine di input tastiera per il monitor esadecimale ; Sostituisce la 80AA e accetta l'input dalla tastiera alfanumerica vecchia o nuova ; o dalla tastiera esadecimale convertendo il valore ricevuto in modo da essere ; compatibile con la 80AA ; ; Dati ricevuti dalla tastiera: ; Numeri da 0 a 9: da 30h a 39h ; Lettere da A ad F: da 61h a 66h ; Shift+numero da 1 a 9: da 21h a 29h ; Shift+lettere da A ad F: da 41h a 46h ; Return: 0dh input: push bc push de push hl t1: call chect ; Se non c'è la scheda video vecchia salta il controllo e passa subito alla tastiera nuova jr nz,t2 t1x: in a,(0eah) ; tastiera vecchia bit 7,a jr nz,t1x t2: in a,(085h) ; tastiera nuova bit 7,a jr z,t2 t2es1: ld hl,0456h ; tastiera esadecimale t2es2: in a,(0f0h) bit 7,a jr z,t2es1 t2es3: dec hl ld a,h or l jr nz,t2es2 ; Input da tastiere t2a: call chect ; Se non c'è la scheda video vecchia salta il controllo e passa subito alla tastiera nuova jr nz,t2ax in a,(0eah) ; tastiera vecchia bit 7,a jr nz,t2b t2ax: in a,(085h) ; tastiera nuova cpl bit 7,a jr nz,t2b in a,(0f0h) ; tastiera esadecimale bit 7,a jr z,tes4 jr t2a ; se non ho premuto nulla sulle tre tastiere allora looppa ; Input da tastiera esadecimale tes1: ld hl,0456h tes2: in a,(0f0h) bit 7,a jr z,tes1 tes3: dec hl ld a,h or l jr nz,tes2 tes4: in a,(0f0h) bit 7,a jr nz,tes4 ld b,a ld hl,0005h call rit tes5: in a,(0f0h) ld c,a and 7fh cp b jr nz,tes5 bit 7,c jr nz,tes1 tes6: jr texit ; Conversione dato per tastiere alfanumeriche t2b: and 7fh cp 0dh ; controlla se è stato premuto RETURN jr nz,t3 ld a,10h ; se si carica il valore di Control+0 jr texit t3: ld b,a ; salva il registro A exx ; recupera il registro D' ld a,d exx or a ; cp 00h - Se <> 0 deve controllare anche il BACKSPACE ld a,b ; ripristina il registro A jr z,t3b cp 08h ; controlla se è stato premuto BACKSPACE jr nz,t3b ld a,01fh ; se si carica il valore 01fh (equivalente a CTRL+F sulla tastiera esadecimale) jr texit t3b: cp 03ah ; controlla se è stato premuto un numero jr nc,t4 cp 030h jr c,t4 sub 030h ; se si sottrae 30h ed esce jr texit t4: cp 67h ; controlla se è stata premuta una lettera tra A ed F jr nc,t5 cp 61h jr c,t5 sub 57h ; se si sottrae 57h ed esce jr texit t5: cp 2ah ; controlla se è stato premuto shift+numero (escluso 0) jr nc,t6 cp 21h jr c,t6 sub 10h ; se si sottrae 10h ed esce jr texit t6: cp 47h ; controlla se è stato premuto shift+lettera da A ad F jr nc,t7 cp 41h jr c,t7 sub 27h ; se si sottrae 27h ed esce jr texit t7: jp t1 texit: pop hl pop de pop bc ret ; Genera un ritardo rit: push hl push af rit1: call rit2 dec hl ld a,h or l jr nz,rit1 pop af pop hl ret rit2: push af push de ld de,0047h rit3: dec de ld a,d or e jr nz,rit3 pop de pop af ret ;------------------------------------------------------ ; ; Nuova routine di output su video per monitor esadecimale ; Sostituisce la 80EC e accetta l'input dalle locazioni da 0000h a 0007h ; convertendo il valore letto in modo da essere compatibile con la 80EC ; Con l'entry point "video1" i registri BC, DE e HL devono essere già impostati ; video: push af push bc push de push hl ld a,20h ; spegne il cursore sul video nuovo call cursor ld de,0007h ; contatore numero di caratteri da visualizzare (indica anche la locazione da cui prelevare il carattere da visualizzare) ld bc,0ec00h ; posizione video vecchio ld hl,0000h ; posizione video nuovo ld a,20h ; spegne il cursore sul video nuovo call cursor m1: push hl ; salva la posizione del video nuovo ld hl,tabvid ; calcola il carattere da visualizzare leggendolo dalla tabella di conversione push bc ld a,(de) ; legge il valore da visualizzare ld b,0h ; lo converte nel carattere ascii ld c,a add hl,bc pop bc ld a,(hl) ; legge dalla tabella il carattere da visualizzare call chect ; controlla se esiste la scheda video vecchia jr nz,m2 ; se non esiste non visualizza il carattere sulla scheda video vecchia call waitv ; attende la ritraccia video vecchio ld (bc),a ; visualizza il carattere sul video vecchio m2: pop hl ; ripristina la posizione del video nuovo call lf060 ; carica in R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare call writen ; visualizza il carattere sul video nuovo inc c ; incrementa la posizione del video vecchio inc l ; incrementa la posizione del video nuovo dec e ; decrementa il contatore dei caratteri da visualizzare ld a,e ; controlla se ci sono altri caratteri da visualizzare cp 0ffh jr nz,m1 ; looppa se ci sono altri caratteri da visualizzare ;------------------------------------------------------ ; Visualizza sui display della tastiera esadecimale ;------------------------------------------------------ ld bc,00f7h ; porta di output del display ld de,0007h ; valore da visualizzare m3: ld hl,tabdis ; carica l'indirizzo della tabella di conversione in HL ld a,(de) ; legge il valore da visualizzare e lo mette in A push bc ; carica il valore da visualizzare in BC ld c,a xor a ld b,a add hl,bc ; HL ora punta all'indirizzo contenente il valore convertito pop bc ld a,(hl) ; carica il valore convertito in A out (c),a ; e lo invia al display dec e ; decrementa e passa al prossimo display/valore dec c ld a,c cp 0efh jr nz,m3 ; (-16) pop hl pop de pop bc pop af ret tabvid: .byte "0123456789ABCDEF" .byte "-", " ", "M", "R", "#", "H", "L", "P", "C", "G" .byte "NQRTUVJY S" ;------------------------------------------------------ ; Tabella caratteri display ; Valori per l'accensione dei segmenti del display: ; ; 1 ; - bit a 1 spegne il segmento ; 32 | | 2 ; - 64 F0 = display a destra ; 16 | | 4 !! ; - F7 = display a sinistra ; 8 ; 128 = punto decimale ; tabdis: .byte 0c0h ;carattere 0 "0" .byte 0f9h ;carattere 1 "1" .byte 0a4h ;carattere 2 "2" .byte 0b0h ;carattere 3 "3" .byte 099h ;carattere 4 "4" .byte 092h ;carattere 5 "5" o "S" .byte 082h ;carattere 6 "6" .byte 0f8h ;carattere 7 "7" .byte 080h ;carattere 8 "8" .byte 090h ;carattere 9 "9" .byte 088h ;carattere 0A "A" .byte 083h ;carattere 0B "b" .byte 0c6h ;carattere 0C "C" .byte 0a1h ;carattere 0d "d" .byte 086h ;carattere 0E "E" .byte 08eh ;carattere 0F "F" .byte 0bfh ;carattere 10 "-" .byte 0ffh ;carattere 11 " " blank .byte 0abh ;carattere 12 "n" bassa .byte 09dh ;carattere 13 "u" alta .byte 0b6h ;carattere 14 "3" linee orizzontali" .byte 089h ;carattere 15 "H" .byte 0c7h ;carattere 16 "L" .byte 08ch ;carattere 17 "P" .byte 0a7h ;carattere 18 "c" bassa .byte 0c2h ;carattere 19 "G" .byte 0c8h ;carattere 1A "N" .byte 098h ;carattere 1B "q" .byte 0afh ;carattere 1C "r" .byte 087h ;carattere 1D "t" .byte 0c1h ;carattere 1E "U" .byte 0e3h ;carattere 1F "u" bassa .byte 0e1h ;carattere 20 "J" .byte 091h ;carattere 21 "Y" .byte 0ffh ;carattere 22 " " blank .byte 0ffh ;carattere 23 " " blank ;------------------------------------------------------ ; Visualizza un messaggio puntato da HL sui display ; Il messaggio da visualizzare deve essere già nel formato compatibile con i caratteri dei display, e deve essere lungo 8 bytes vdisp: push af push bc push hl ld c,0f7h ; indirizzo del primo display vdisp1: ld a,(hl) ; carica il carattere da visualizzare in A out (c),a ; e lo invia al display inc hl ; punta al prossimo carattere da visualizzare dec c ; punta al prossimo display ld a,c cp 0efh jr nz,vdisp1 pop hl pop bc pop af ret ;------------------------------------------------------ ; Visualizza il carattere contenuto in A sul display puntato da C, convertendolo nel formato compatibile con i caratteri dei display vdispc: push hl push af push bc ld hl,tabdis ; carica l'indirizzo della tabella di conversione in HL ld c,a ; carica il valore da visualizzare in BC xor a ld b,a add hl,bc ; HL ora punta all'indirizzo contenente il valore convertito ld a,(hl) ; carica il valore convertito in A pop bc out (c),a ; invia il valore convertito al display pop af pop hl ret ;------------------------------------------------------ ; Routine f060h della eprom 2390 (carica in R14, R15, R18 e R19 l'indirizzo (HL) del cursore e del carattere da visualizzare) ; Routine f06eh della eprom 2390 (carica in R18 e R19 l'indirizzo (HL) del carattere da visualizzare) lf060: push af ld a,0eh ; carica da HL l'indirizzo del cursore out (8ch),a ld a,h out (8dh),a ld a,0fh out (8ch),a ld a,l out (8dh),a pop af lf06e: push af ld a,12h ; carica da HL l'indirizzo del carattere da visualizzare in R18 e R19 out (8ch),a ld a,h out (8dh),a ld a,13h out (8ch),a ld a,l out (8dh),a ld a,1fh ; accesso a R31 del SY6545 per fare l'update out (8ch),a pop af ret ;------------------------------------------------------ ; Routine f0a5h della eprom 2390 (inizializza i registri del SY6545 ed i PIO) lf0a5: in a,(89h) ; setta il video a 80 colonne res 1,a ld hl,tabini ; carica in HL l'indirizzo della tabella contenente i parametri di inizializzazione del video nuovo out (89h),a ld a,8fh ; inizializza i PIO out (82h),a ; PIO 0/A (RAM 0) out (86h),a ; PIO 1/A (RAM 1) out (8ah),a ; PIO 2/A (RAM 2) ld a,0cfh out (83h),a ; PIO 0/B (stampante) ex af,af' xor a out (83h),a ex af,af' out (87h),a ; PIO 1/B (tastiera) ex af,af' dec a out (87h),a ex af,af' out (8bh),a ; PIO 2/B (busy stampante / controllo 40-80 caratteri) ld a,0f1h out (8bh),a ld b,0ch ; inizializza i registri del SY6545 da R11 a R0 lf0ce: ld a,b dec a out (8ch),a ld a,(hl) out (8dh),a inc hl djnz lf0ce ; (-10) lf0d8: ld b,08h ; azzera i registri del SY6545 da R19 a R12 lf0da: ld a,b add a,0bh out (8ch),a xor a out (8dh),a djnz lf0da ; (-10) lf086: ld a,1fh ; accesso a R31 del SY6545 per fare l'update out (8ch),a ret tabini: .byte 0bh, 00h, 0bh, 48h, 18h, 18h, 00h, 1ah, 28h, 57h, 50h, 6fh ;------------------------------------------------------ ; Calcola l'indirizzo della tabella TABDIS e lo ritorna in HL ctabdi: ld hl,tabdis ret ;------------------------------------------------------ ; Jump table per il richiamo della routine di gestione della voce di menu selezionata tabtas: .dw tast1 .dw tast2 .dw tast3 .dw tast4 .dw tast5 .dw tast6 .dw tast7 .dw tast8 .dw tast9 .dw tastA .dw tastB .dw tastC .dw tastD .dw tastE .dw tastF .dw tast10 .dw tast11 .dw tast12 ;------------------------------------------------------ ; Jump table per il richiamo della routine di visualizzazione della pagina di menù tabmen: .dw vmenu1 .dw vmenu2 .dw vmenu3 ;------------------------------------------------------ .org 0ffffh .byte 00h .end